import axios from 'axios';
import { appLocalStorage } from '@/utils/storage-util.js';
import { AppComstants } from '@/common/comstants';
import router from '@/router';
import { ElMessage } from 'element-plus';

/**
 * 创建带自定义配置的axios实例
 * @type {import('axios').AxiosInstance}
 */
const service = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: import.meta.env.VITE_API_TIMEOUT || 3000,
  headers: { 'Content-Type': 'application/json' },
});

/**
 * 请求拦截器（执行顺序：后添加的先执行）
 * 主要职责：
 * 1. 自动携带认证token
 * 2. 统一请求参数处理
 * @param {import('axios').InternalAxiosRequestConfig} config
 * @returns {Promise<import('axios').InternalAxiosRequestConfig>}
 */
service.interceptors.request.use(
  (config) => {
    const token = appLocalStorage.getItem(AppComstants.Token);
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

/**
 * 响应拦截器（执行顺序：先添加的先执行）
 * 主要职责：
 * 1. 处理二进制响应数据
 * 2. 统一响应数据结构
 * @param {import('axios').AxiosResponse} response
 * @returns {Promise<any>}
 */
service.interceptors.response.use((response) => {
  // 处理二进制数据
  if (response.headers['content-type']?.includes('application/octet-stream')) {
    return response;
  }
  return response.data;
}, handleResponseError);

/**
 * 请求重试配置（需配合axios-retry插件使用）
 * @property {number} retry - 最大重试次数（默认3次）
 * @property {number} retryDelay - 重试延迟时间（单位毫秒）
 * @property {(error: import('axios').AxiosError) => boolean} shouldRetry - 重试条件判断
 */
service.defaults.retry = 3;
service.defaults.retryDelay = 1000;
service.defaults.shouldRetry = (error) => {
  return error.code === 'ECONNABORTED' 
    || error.response?.status >= 500 
    || !error.response;
};

/**
 * 响应错误统一处理流程图：
 * [网络错误] -> 显示网络错误提示
 * [401未授权] -> 清除token -> 跳转登录
 * [400参数错误] -> 展示具体错误信息
 * [500服务器错误] -> 显示服务器错误提示
 * [其他状态码] -> 显示通用错误提示
 */
function handleErrorMessage(error) {
  let message = '';
  if (Array.isArray(error.response.data?.message)) {
    message = error.response.data.message.join('<br/>');
  } else {
    message = error.response.data.message;
  }
  ElMessage({
    type: 'error',
    dangerouslyUseHTMLString: true,
    message,
  });
  return message;
}

/**
 * 处理响应错误的函数
 * @param {import('axios').AxiosError} error - axios错误对象
 * @returns {Promise<never>} 返回一个被拒绝的Promise，携带原始错误对象
 */
function handleResponseError(error) {
  if (error.response) {
    switch (error.response.status) {
      case 400:
        handleErrorMessage(error);
        break;
      case 401:
        ElMessage.error('登录已经失效，请先登录！');
        appLocalStorage.removeItem(AppComstants.Token);
        router.push('/login');
        break;
      case 413:
        handleErrorMessage(error);
        break;
      case 500:
        ElMessage.error('服务器异常，请联系管理员！');
        break;
      default:
        ElMessage.error(`请求失败，状态码: ${error.response.status}`);
    }
  } 
  else if (error.request) {
    ElMessage.error('请求发送失败，请检查网络连接。');
  } 
  else {
    ElMessage.error('请求初始化失败，请稍后再试。');
  }

  return Promise.reject(error);
}

export default service;
